#version 140

uniform vec4 instance_positions[512];
in vec4 vertices;
in vec3 normals;
in vec4 texcoords;

uniform mat4 matrix_projection;
uniform mat4 matrix_world;
uniform mat4 matrix_view;

uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 light_position;
uniform float light_range;

uniform vec4 material_ambient;
uniform vec4 material_diffuse;
uniform vec4 material_specular;
uniform float material_shininess;
uniform vec4 material_emission;

uniform vec4	wind;
uniform float	time;

out vec2 texCoord;
out vec4 color;

mat4 matrix_modelview = matrix_view * matrix_world;

void main(void)
{
  vec4 instance_position = instance_positions[gl_InstanceID];

  float timeVal = cos (time + instance_position.w) + 0.5;
  vec3 v = vertices.xyz + vec3 (wind.xy * wind.w * timeVal, 0.0) * vertices.z;

  vec4 pos = vec4 (v + instance_position.xyz, 1.0);
	vec4 cam_pos = matrix_modelview * pos;

  texCoord = texcoords.xy;

  vec3 normal = (matrix_modelview * vec4(normals, 0.0)).xyz;
	vec3 v_to_l   = (matrix_view * light_position).xyz - cam_pos.xyz;
  float distance = length (v_to_l);
  v_to_l = normalize (v_to_l);
	vec3 v_to_e   = normalize (-cam_pos.xyz);

  color = light_ambient * material_ambient;

  // the diffuse term
  float dt = max(0.0, (dot (v_to_l, normal)));
  color += dt * light_diffuse * material_diffuse;

  // the specular terim
  vec3 half = normalize (v_to_e + v_to_l);
  float st = pow(max(0.0, min(1.0, dot(normal, half))), material_shininess);
  color += st * light_specular * material_specular;

  color += material_emission;

  float lightIntensity = clamp(1.0 - distance / light_range, 0.0, 1.0f);
  color *= lightIntensity;

  color = clamp (color, 0, 1);

	gl_Position = matrix_projection * matrix_view * matrix_world * pos;
}
